package com.xiaoge.controller;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.xiaoge.annotation.ControllerEndpoint;
import com.xiaoge.converter.RoleConverter;
import com.xiaoge.entity.Role;
import com.xiaoge.entity.User;
import com.xiaoge.exception.BusinessException;
import com.xiaoge.response.Result;
import com.xiaoge.service.RoleService;
import com.xiaoge.service.UserService;
import com.xiaoge.vo.MenuNodeVO;
import com.xiaoge.vo.RoleTransferItemVO;
import com.xiaoge.vo.UserInfoVO;
import com.xiaoge.vo.UserVO;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * 用户表 前端控制器
 * </p>
 *
 * @author XiaoGe
 * @since 2022-05-28
 */
@Api(value = "用户管理", tags = "用户测试")
@RestController
@RequestMapping("/user")
public class UserController {

    @Autowired
    private UserService userService;

    @Autowired
    private RoleService roleService;

    /**
     * 后台用户登入
     *
     * @param username: 用户名
     * @param password: 密码
     * @return
     */
    @ApiOperation(value = "用户登入", notes = "接收参数用户名和密码,登入成功后,返回JWTToken")
    @PostMapping("/login")
    public Result login(@RequestParam(value = "username",required = true) String username,
                        @RequestParam(value = "password",required = true) String password,
                              HttpServletRequest request) {
        System.out.println(username+password);
        String token=userService.login(username,password);
        return Result.ok().data("token",token);
    }

    /**
     * 用户信息
     *
     * @return
     */
    @ApiOperation(value = "用户信息", notes = "用户登入信息")
    @GetMapping("/info")
    public Result info() {
        UserInfoVO userInfoVO=userService.info();
        return Result.ok().data("userInfoVO",userInfoVO);
    }

    /**
     * 加载菜单
     *
     * @return
     */
    @ApiOperation(value = "加载菜单", notes = "用户登入后,根据角色加载菜单树")
    @GetMapping("/getMenu")
    public Result getMenu() {
        List<MenuNodeVO> menuTreeVOS = userService.getMenu();
        return Result.ok().data("menuTreeVOS",menuTreeVOS);
    }


    /**
     * 功能描述: <br>
     * 〈模糊+条件获取用户信息〉
     * @Param: [current, size, userVO]
     * @Return: com.xiaoge.response.Result
     * @Author: Mr.Nie
     * @Date: 2022/6/10 15:27
     */
    @ApiOperation(value = "用户列表", notes = "模糊查询用户列表")
    @PostMapping("/getUserList")
    public Result getUserList(@RequestParam(value = "current",required = true,defaultValue = "1") Integer current,
                              @RequestParam(value = "size",required = true,defaultValue = "7") Integer size,
                              @RequestBody UserVO userVO){
        Page<User> page = new Page<>(current,size);
        Page<User> userPage = userService.getUserByPage(page,userVO);
        return Result.ok().data("userPage",userPage);
    }

    /**
     * 添加用户信息
     * @param user
     * @return
     */
    @ControllerEndpoint(exceptionMessage = "添加用户失败", operation = "添加用户")
    @ApiOperation(value = "添加用户", notes = "添加用户信息")
    @RequiresPermissions({"user:add"})
    @PostMapping("/add")
    public Result add(@RequestBody User user) {
        userService.add(user);
        return Result.ok();
    }

    /**
     * 编辑用户
     * @param id
     * @return
     */
    @ApiOperation(value = "编辑用户", notes = "获取用户的详情，编辑用户信息")
    @RequiresPermissions({"user:edit"})
    @GetMapping("/edit/{id}")
    public Result edit(@PathVariable Long id) {
        User user = userService.getById(id);
        if(user==null){
            throw new BusinessException("要编辑的用户不存在");
        }
        return Result.ok().data("user",user);
    }

    /**
     * 更新用户
     * @param user
     * @return
     */
    @ControllerEndpoint(exceptionMessage = "更新用户失败", operation = "更新用户")
    @ApiOperation(value = "更新用户", notes = "更新用户信息")
    @RequiresPermissions({"user:update"})
    @PutMapping("/update")
    public Result update(@RequestBody @Validated User user) {
        System.out.println(user.toString());
        userService.updateUser(user);
        return Result.ok();
    }

    /**
     * 删除用户
     *
     * @param id 用户ID
     * @return
     */
    @ControllerEndpoint(exceptionMessage = "删除用户失败", operation = "删除用户")
    @RequiresPermissions({"user:delete"})
    @ApiOperation(value = "删除用户", notes = "删除用户信息，根据用户ID")
    @DeleteMapping("/delete/{id}")
    public Result delete(@PathVariable Long id) {
        userService.removeById(id);
        return Result.ok();
    }

    /**
     * 用户角色信息
     * @param id
     * @return
     */
    @ApiOperation(value = "已有角色", notes = "根据用户id，获取用户已经拥有的角色")
    @GetMapping("/roles/{id}")
    public Result roles(@PathVariable Long id) {
        List<Long> values = userService.roles(id);
        List<Role> list = roleService.list();
        //转成前端需要的角色Item
        List<RoleTransferItemVO> items = RoleConverter.converterToRoleTransferItem(list);
        Map<String, Object> map = new HashMap<>();
        map.put("roles", items);
        map.put("values", values);
        return Result.ok().data(map);
    }

    /**
     * 分配角色
     *
     * @param id
     * @param rids
     * @return
     */
    @ControllerEndpoint(exceptionMessage = "分配角色失败", operation = "分配角色")
    @ApiOperation(value = "分配角色", notes = "角色分配给用户")
    @RequiresPermissions({"user:assign"})
    @PostMapping("/assignRoles/{id}")
    public Result assignRoles(@PathVariable Long id, @RequestBody Long[] rids) {
        userService.assignRoles(id, rids);
        return Result.ok();
    }

    /**
     * 更新状态
     *
     * @param id
     * @param status
     * @return
     */
    @ControllerEndpoint(exceptionMessage = "更新用户状态失败", operation = "用户|禁用/启用")
    @ApiOperation(value = "用户状态", notes = "禁用和启用这两种状态")
    @RequiresPermissions({"user:status"})
    @PutMapping("/updateStatus/{id}/{status}")
    public Result updateStatus(@PathVariable Long id, @PathVariable Boolean status) {
        userService.updateStatus(id, status);
        return Result.ok();
    }


}
